﻿using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DiscreteMath.Tests
{
    class EquivalenceTester
    {
        public EquivalenceTester(int testCount, WordGenerator generator)
        {
            this.TestCount = testCount;
            this.Generator = generator;
        }

        public int TestCount { get; set; }

        public WordGenerator Generator { get; set; }

        public void TestEquivalence(ILanguageRecognizer first, ILanguageRecognizer second, string message)
        {
            TestEquivalence(first.ReadWord, second.ReadWord, message, Assert.AreEqual);
        }

        public void TestInequality(ILanguageRecognizer first, ILanguageRecognizer second, string message)
        {
            TestEquivalence(first.ReadWord, second.ReadWord, message, Assert.AreNotEqual);
        }

        public void TestEquivalence(ILanguageGenerator generator, ILanguageRecognizer recognizer, string message)
        {
            TestEquivalence(generator.GenerateWord, recognizer.ReadWord, message);
        }

        public void TestEquivalence(
            Func<string, bool> first, 
            Func<string, bool> second, 
            string message,
            Action<bool, bool, string> testFunction)
        {
            for (int i = 0; i < this.TestCount; i++)
            {
                var word = this.Generator.GenerateWord(i);
                testFunction(first(word), second(word), message);
            }
        }

        public void TestEquivalence(
            Func<string> first,
            Func<string, bool> second, 
            string message)
        {
            for (int i = 0; i < this.TestCount; i++)
            {
                string word = first();
                Assert.IsTrue(second(word), message);
            }
        }

        public void TestEquivalence(
            Func<string, bool> first, 
            Func<string, bool> second, 
            string message,
            Action<bool, bool, string> testFunction, 
            int maxWordLength)
        {
            for (int i = 0; i < this.TestCount; i++)
            {
                var word = this.Generator.GenerateWord(maxWordLength);
                testFunction(first(word), second(word), message);
            }
        }
    }
}
